package com.zerowidth.moc.web.utils;

import com.alibaba.fastjson.JSONObject;
import org.springframework.util.DigestUtils;

import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

public class SignUtils {

    private static final String SIGN_SALT = "98cadfc3f7736f4adccb69b6449d8c96";

    private static final String SIGN_KEY = "sign";
    //请求的参数中带有此key时，才表示客户端尝试要求跳过签名校验
    private static final String SIGN_UNLOCK_KEY = "xdqregf";
    //跳过签名校验的对称密钥
    private static final String SIGN_UNLOCK_CMD = "17064hfdauohr";

    /**
     * 是否跳过签名检验
     *
     * @param params 请求所有的参数
     * @return
     */
    public static boolean isEscapeSign(SortedMap<String, String> params) {
        String urlSignUnlock = params.get(SIGN_UNLOCK_KEY);
        if (StringUtils.equals(urlSignUnlock, SIGN_UNLOCK_CMD)) {
            return true;
        }
        return false;
    }

    /**
     * 校验 url里携带的签名 是否与 服务器重新计算的签名 相同
     *
     * @param params            所有的请求参数都会在这里进行排序加密
     * @param generateSignValue 从url中的所有参数重新计算出的签名
     * @return 验证签名结果
     */
    public static boolean verifySign(SortedMap<String, String> params, String generateSignValue) {
        if (params == null) {
            return false;
        }

        String urlSignUnlock = params.get(SIGN_UNLOCK_KEY);
        if (StringUtils.equals(urlSignUnlock, SIGN_UNLOCK_KEY)) {
            return true;
        }

        String urlSign = params.get(SIGN_KEY);
        LogUtils.info(String.format("请求里携带的原始签名:%s", urlSign));
        if (StringUtils.isEmpty(urlSign)) {
            //没有需要签名的参数，默认为 不通过签名校验
            return false;
        }

        return !StringUtils.isEmpty(urlSign) && urlSign.equals(generateSignValue);
    }

    /**
     * @param params 所有的请求参数都会在这里进行排序加密
     * @return 得到签名
     */
    public static String generateSign(String url, SortedMap<String, String> params) {

        String paramsJsonStr = "";

        if (CollectionUtils.isNotEmpty(params)) {
            SortedMap<String, String> tmepParams = new TreeMap<>();

            Iterator<Map.Entry<String, String>> iterator = params.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, String> entry = iterator.next();
                tmepParams.put(entry.getKey(), entry.getValue());
            }

            //去掉 Url 里的 Sign
            tmepParams.remove(SIGN_KEY);
            //去掉跳过签名检验的口令
            tmepParams.remove(SIGN_UNLOCK_KEY);
            paramsJsonStr = JSONObject.toJSONString(tmepParams);
        }


        return DigestUtils.md5DigestAsHex((SIGN_SALT + url + paramsJsonStr).getBytes()).toLowerCase();
    }

}